package com.nx.project.javacore.countrt;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 作业：统计，通过注解实现一下
 * 使用动态代理的方式代码增强
 */
public class CountRuntimeMaintest {

    public static void main(String[] args) {
        //待增强的目标类
        CountRuntime target = new CountRuntime();

        //JDK动态代理
        ICountRuntime proxy = (ICountRuntime)Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //利用反射进行代码增强
                        //获取目标类的目标方法
                        Class<? extends CountRuntime> c = target.getClass();
                        Method m;
                        if(args == null){
                            //获取目标类的真实方法（需要增强的方法），如果方法中有@Runtime注解，那么就增强这个方法
                            m = c.getDeclaredMethod(method.getName());//只能获取无参的方法
                        }else{
                            Class[] paramArgs = new Class[args.length];
                            for (int i = 0; i < paramArgs.length; i++) {
                                paramArgs[i] = args[i].getClass();
                            }
                            m = c.getMethod(method.getName(),paramArgs);//方法的名字，参数
                        }
                        RunTime annotation = m.getAnnotation(RunTime.class);
                        if(annotation != null){
                            long start = System.currentTimeMillis();
                            //执行原方法
                            Object result = method.invoke(target, args);//方法的返回结果
                            long end = System.currentTimeMillis();
                            System.out.println("方法："+ method.getName() + " 执行时间:" + (end - start));
                        }
                        return method.invoke(target, args);
                    }
                }
        );

        //执行方法
        proxy.method01();//调用代理对象的方法，就可以增强了
        proxy.method02("123");
    }
}
